package com.kevin.swing.impl;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import com.kevin.MainFrame;
import com.kevin.model.db.DB;
import com.kevin.model.db.DBSetInfo;
import com.kevin.service.DBTabelService;
import com.kevin.util.CacheUtil;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.log4j.Log4j;

/**
 * 数据库配置
 * 
 * @ClassName DBSetDialog
 * @author <a href="mailto:donggongai@126.com" target="_blank">kevin</a>
 * @date 2016年8月25日 下午4:45:24
 *
 */
@EqualsAndHashCode(callSuper = false)
@Log4j
public @Data class DBSetDialog extends JDialog {
    private MainFrame owner;

    /**
     * 
     */
    private static final long serialVersionUID = 6792501234970255123L;

    private JPanel wordSetDemoJPanel; // 数据库设置Demo
    private JLabel dbTypeLabel; // 数据库类型
    private JComboBox<String> dbTypeComboBox; // 下拉列表
    private JLabel dbUrlDemoLabel; // 数据库url示例
    private JTextField dbUrlDemoText; // 数据库url示例

    private JPanel wordSetJPanel; // 数据库设置
    private JLabel dbConsLabel; // 保存的连接
    private JComboBox<String> dbConsComboBox; // 下拉列表
    // 右键
    private JButton delConsBtn = new JButton("删除");

    private JLabel dbSetNameLabel; // 数据库设置名称
    private JTextField dbSetNameText; // 数据库设置名称保存
    private JLabel dburlLabel; // 数据库url
    private JTextField dburlText;
    private JLabel dbUsernameLabel; // 数据库用户名
    private JTextField dbUsernameText;
    private JLabel dbPasswordLabel; // 数据库密码
    private JPasswordField dbPasswordText;

    private JPanel btnPanel = new JPanel();
    private JButton okbtn = new JButton("保存");
    private JButton clbtn = new JButton("重置");
    private JButton conbtn = new JButton("测试连接");

    public DBSetDialog(MainFrame owner) {
        super();
        this.owner = owner;
        // 数据库URL工具
        wordSetDemoJPanel = new JPanel();
        wordSetDemoJPanel.setBorder(BorderFactory.createTitledBorder("数据库URL工具"));

        dbTypeLabel = new JLabel("数据库：");
        dbTypeComboBox = new JComboBox<>(); // 下拉列表
        dbTypeComboBox.addItem("选择");
        dbTypeComboBox.addItem(DB.ORACLE);
        dbTypeComboBox.addItem(DB.MYSQL);

        dbTypeComboBox.addItemListener((e) -> {
            switch (e.getStateChange()) {
                case ItemEvent.SELECTED:
                    String item = (String) dbTypeComboBox.getSelectedItem();
                    if (DB.ORACLE == item) {
                        dbUrlDemoText.setText("jdbc:oracle:thin:@//127.0.0.1:1521/orcl");
                    } else if (DB.MYSQL == item) {
                        dbUrlDemoText.setText("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8");

                    }
                    break;
            }
        }); // 添加事件处理
        dbUrlDemoLabel = new JLabel("URL示例：");
        dbUrlDemoText = new JTextField("");

        wordSetDemoJPanel.setLayout(new GridBagLayout());

        wordSetDemoJPanel.add(dbTypeLabel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
                new Insets(0, 0, 0, 0), 0, 0));
        wordSetDemoJPanel.add(dbTypeComboBox, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.WEST,
                GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));

        wordSetDemoJPanel.add(dbUrlDemoLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
                new Insets(0, 0, 0, 0), 0, 0));
        wordSetDemoJPanel.add(dbUrlDemoText, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST,
                GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
        // 设置JPanel
        wordSetJPanel = new JPanel();
        wordSetJPanel.setBorder(BorderFactory.createTitledBorder("数据库设置"));

        dbConsLabel = new JLabel("保存的连接："); // 保存的连接
        dbConsComboBox = new JComboBox<>(); // 下拉列表
        dbConsComboBox.addItem("选择");
        try {
            List<String> dbConsName = CacheUtil.get("dbcons");
            if (dbConsName != null) {
                dbConsName.stream().forEach(conName -> dbConsComboBox.addItem(conName));
                dbConsComboBox.addItemListener((e) -> {
                    switch (e.getStateChange()) {
                        case ItemEvent.SELECTED:
                            String itemName = (String) dbConsComboBox.getSelectedItem();
                            Map<String, String> dbSet;
                            try {
                                dbSet = CacheUtil.get("db_" + itemName);
                                if (dbSet != null) {
                                    String dbSetName = dbSet.get("DbSetName");
                                    String dburl = dbSet.get("DbUrl");
                                    String username = dbSet.get("DbUserName");
                                    String password = dbSet.get("DbPassword");
                                    dbSetNameText.setText(dbSetName);
                                    dburlText.setText(dburl);
                                    dbUsernameText.setText(username);
                                    dbPasswordText.setText(password);
                                    DBSetInfo.setDbSetName(dbSetName);
                                    DBSetInfo.setDbUrl(dburl);
                                    DBSetInfo.setDbUserName(username);
                                    DBSetInfo.setDbPassword(password);
                                    owner.loadDBTableService(); // 重新加载数据库服务类
                                }
                            } catch (Exception e1) {
                                log.error("缓存获取失败！", e1);
                            }
                            break;
                    }
                }); // 添加事件处理
            }
        } catch (Exception e1) {
            log.error("缓存获取失败！", e1);
        }
        delConsBtn.addActionListener(e -> {
            String msg = "确定要删除该连接吗？";
            int i = JOptionPane.showConfirmDialog(DBSetDialog.this, msg, "提醒", JOptionPane.YES_NO_OPTION);
            if (i == JOptionPane.NO_OPTION) {
                return;
            }
            String itemName = (String) dbConsComboBox.getSelectedItem();
            if (!"选择".equals(itemName)) {
                dbConsComboBox.removeItem(itemName);
                Map<String, String> dbSet;
                try {
                    dbSet = CacheUtil.get("db_" + itemName);
                    if (dbSet != null) {
                        CacheUtil.remove("db_" + itemName);
                    }
                    List<String> dbConsName = CacheUtil.get("dbcons");
                    if (dbConsName == null) {
                        dbConsName = new ArrayList<>();
                    }
                    if (dbConsName.contains(itemName)) {
                        dbConsName.remove(itemName);
                        CacheUtil.put("dbcons", dbConsName);
                    }
                } catch (Exception e1) {
                    log.error("缓存获取失败！", e1);
                }
            }
        });

        dbSetNameLabel = new JLabel("连接名："); // 数据库设置名称
        dbSetNameText = new JTextField(); // 数据库设置名称保存
        dburlLabel = new JLabel("url：");
        dburlText = new JTextField();
        dbUsernameLabel = new JLabel("用户名：");
        dbUsernameText = new JTextField();
        dbPasswordLabel = new JLabel("密码：");
        dbPasswordText = new JPasswordField();
        loadDBSetInfo();
        wordSetJPanel.setLayout(new GridBagLayout());

        // 参数分别表示x轴相对位置（0开始）、y轴相对位置（0开始）、x轴宽度、y轴高度、x轴不自动扩展（0不扩展1扩展）、y轴不自动扩展（0不扩展1扩展）
        wordSetJPanel.add(dbConsLabel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
                new Insets(0, 0, 0, 0), 0, 0));
        wordSetJPanel.add(dbConsComboBox, new GridBagConstraints(1, 0, 2, 1, 1.0, 0.0, GridBagConstraints.WEST,
                GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
        JPanel consPanel = new JPanel();
        consPanel.add(delConsBtn); // jpanel用于增加左右边距
        wordSetJPanel.add(consPanel, new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
                new Insets(0, 0, 0, 0), 0, 0));

        wordSetJPanel.add(dbSetNameLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
                new Insets(0, 0, 0, 0), 0, 0));
        wordSetJPanel.add(dbSetNameText, new GridBagConstraints(1, 1, 3, 1, 1.0, 0.0, GridBagConstraints.WEST,
                GridBagConstraints.HORIZONTAL, new Insets(0, 1, 0, 0), 0, 0));

        wordSetJPanel.add(dburlLabel, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
                new Insets(0, 0, 0, 0), 0, 0));
        wordSetJPanel.add(dburlText, new GridBagConstraints(1, 2, 3, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
                new Insets(0, 0, 0, 0), 0, 0));

        wordSetJPanel.add(dbUsernameLabel, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
                new Insets(0, 0, 0, 0), 0, 0));
        wordSetJPanel.add(dbUsernameText, new GridBagConstraints(1, 3, 3, 1, 1.0, 0.0, GridBagConstraints.WEST,
                GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));

        wordSetJPanel.add(dbPasswordLabel, new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
                new Insets(0, 0, 0, 0), 0, 0));
        wordSetJPanel.add(dbPasswordText, new GridBagConstraints(1, 4, 3, 1, 1.0, 0.0, GridBagConstraints.WEST,
                GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));

        btnPanel = new JPanel();
        btnPanel.add(okbtn);
        btnPanel.add(clbtn);
        btnPanel.add(conbtn);

        setTitle("数据库设置");
        add(wordSetDemoJPanel, BorderLayout.NORTH);
        add(wordSetJPanel, BorderLayout.CENTER);
        add(btnPanel, BorderLayout.SOUTH);
        setVisible(false);
        setSize(380, 280);
        setResizable(false);
        init();
    }

    private void loadDBSetInfo() {
        dbSetNameText.setText(DBSetInfo.getDbSetName());
        dburlText.setText(DBSetInfo.getDbUrl());
        dbUsernameText.setText(DBSetInfo.getDbUserName());
        dbPasswordText.setText(DBSetInfo.getDbPassword());
    }

    private void init() {
        clbtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                loadDBSetInfo();
            }
        });

        okbtn.addActionListener(e -> {
            String dbSetName = dbSetNameText.getText();
            try {
                Map<String, String> dbSet = CacheUtil.get("db_" + dbSetName);
                if (dbSet != null) {
                    String msg = "该连接名已经存在，保存将覆盖原连接，是否继续保存？";
                    int i = JOptionPane.showConfirmDialog(DBSetDialog.this, msg, "提醒", JOptionPane.YES_NO_OPTION);
                    if (i == JOptionPane.NO_OPTION) {
                        return;
                    }
                }
            } catch (Exception e1) {
                log.error("缓存获取失败！", e1);
            }
            String url = dburlText.getText();
            String username = dbUsernameText.getText();
            String password = new String(dbPasswordText.getPassword());
            boolean testResult = DBTabelService.testCon(url, username, password);
            if (!testResult) {
                String msg = "连接失败！请检查用户名密码是否错误，是否继续保存？";
                int i = JOptionPane.showConfirmDialog(DBSetDialog.this, msg, "提醒", JOptionPane.YES_NO_OPTION);
                if (i == JOptionPane.NO_OPTION) {
                    return;
                }
            }
            DBSetInfo.setDbSetName(dbSetName);
            DBSetInfo.setDbUrl(url);
            DBSetInfo.setDbUserName(username);
            DBSetInfo.setDbPassword(password);
            // 保存历史记录
            Map<String, String> dbSet = new HashMap<>();
            dbSet.put("DbSetName", dbSetName);
            dbSet.put("DbUrl", url);
            dbSet.put("DbUserName", username);
            dbSet.put("DbPassword", password);
            CacheUtil.put("db_" + dbSetName, dbSet);
            try {
                List<String> dbConsName = CacheUtil.get("dbcons");
                if (dbConsName == null) {
                    dbConsName = new ArrayList<>();
                }
                if (!dbConsName.contains(dbSetName)) {
                    dbConsComboBox.addItem(dbSetName);
                    dbConsName.add(dbSetName);
                    CacheUtil.put("dbcons", dbConsName);
                }
            } catch (Exception e1) {
                log.error("缓存获取失败！", e1);
            }

            owner.loadDBTableService(); // 重新加载数据库服务类
            DBSetDialog.this.setVisible(false);
        });

        conbtn.addActionListener(e -> {
            String url = dburlText.getText();
            String username = dbUsernameText.getText();
            String password = new String(dbPasswordText.getPassword());
            boolean testResult = DBTabelService.testCon(url, username, password);
            String msg = "连接成功！";
            if (!testResult) {
                msg = "连接失败！请返回修改。";
            }
            JOptionPane.showMessageDialog(DBSetDialog.this, msg);
        });

    }
}
